package com.ecld.grpc.server;


import com.ecld.grpc.service.AuthServiceImp;
import com.ecld.grpc.tool.ConnectionPoolUtils;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.logging.*;

public class GRpcServer {

    private static final Logger logger = Logger.getLogger(GRpcServer.class.getName());
    private Server server;

    private void start() throws IOException {

        Properties props = new Properties();
        InputStream in = new BufferedInputStream(new FileInputStream("conf/server.properties"));
        props.load(in);

        int port = Integer.parseInt(props.getProperty ("server.port"));
        server = ServerBuilder
                .forPort(port)
                .addService(new AuthServiceImp())
                .build()
                .start();

        FileHandler fileHandler = new FileHandler(props.getProperty ("server.logdir"));
        fileHandler.setLevel(Level.ALL);
        fileHandler.setFormatter(new Formatter() {
            @Override
            public String format(LogRecord record) {
                return "["+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"]-"
                        +"["+record.getSourceClassName()+"."+record.getSourceMethodName()+"] "
                        +record.getMessage() + "\n";
            }
        });
        logger.addHandler(fileHandler);

//        initDB();

        logger.log(Level.INFO,"Server started, listening on " + port);

        Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run() {
                logger.log(Level.INFO,"*** Shutting down gRPC server since JVM is shutting down");
                GRpcServer.this.stop();
                logger.log(Level.INFO,"*** Server shut down");
            }
        });
    }

    private void initDB() {
        try {
            Connection conn = ConnectionPoolUtils.getInstance().getConnection();
            Statement stmt = conn.createStatement();
            String sql = "CREATE TABLE IF NOT EXISTS USER " +
                    "(UNAME VARCHAR(50) NOT NULL, " +
                    " PASSWD CHAR(50) NOT NULL, " +
                    " TOKEN CHAR(50), " +
                    " VALID_UNTIL FLOAT," +
                    " PRIMARY KEY(UNAME))";
            stmt.executeUpdate(sql);
        } catch (SQLException e) {
            logger.log(Level.WARNING,"Server Init Database Error:"+e.getMessage());
            stop();
        }
    }

    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    private void  blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        final GRpcServer server = new GRpcServer();
        server.start();
        server.blockUntilShutdown();
    }
}
